package slice

func computeCapacity(l, c int) (int, bool) {
	// cap小于32不缩容
	if c <= 32 {
		return c, false
	}

	// cap大于256,len小于八分之五的cap,就开始缩容,减少缩容次数
	if c > 256 && (float64(l)/float64(c) <= 0.625) {
		factor := 0.75 // 缩小1/4,预留部分容量减少 append 时候再度扩容的次数
		return int(float64(c) * factor), true
	}

	// cap小于等于256时,len小于三分之一的cap,就开始缩容,减少缩容次数
	if c <= 256 && (c/l >= 3) {
		return c / 2, true // 缩小一半
	}
	return c, false
}

func Shrink[T any](sli []T) []T {
	l, c := len(sli), cap(sli)
	newCap, changed := computeCapacity(l, c)
	if !changed {
		return sli
	}
	s := make([]T, 0, newCap)
	s = append(s, sli...)
	return s
}
